﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using DACU.Player;
using DACU.Player.Enums;
using DACU.Tools;
using DACU.VkontakteApi;
using DACU.VkontakteApi.Base;
using DACU.VkontakteApi.Collections;
using DACU.Windows;
using Microsoft.Win32;
using System.Windows.Media;
using Un4seen.Bass;
using Track = DACU.Player.Track;
using Utils = DACU.Tools.Utils;

namespace DACU.UserControls.Player
{
	/// <summary>
	/// Логика взаимодействия для PlayList.xaml
	/// </summary>
	public partial class PlayList : INotifyPropertyChanged
	{
		public event PropertyChangedEventHandler PropertyChanged;
		public event TrackChangedEventHandler TrackChanged;
		Playlist _playlist = new Playlist();

		public IEnumerable Source
		{
			get { return lvPlayList.ItemsSource; }
			set
			{
				lvPlayList.ItemsSource = value;
				ChangeProperty("Source");
			}
		}
		public bool IsShuffle
		{
			get { return _playlist.IsShuffle; }
			set
			{
				_playlist.IsShuffle = value;
				ChangeProperty("IsShuffle");
			}
		}
		public bool IsFileLoop
		{
			get { return _playlist.IsFileLoop; }
			set
			{
				_playlist.IsFileLoop = value;
				ChangeProperty("IsFileLoop");
			}
		}
		public bool IsListLoop
		{
			get { return _playlist.IsListLoop; }
			set
			{
				_playlist.IsListLoop = value;
				ChangeProperty("IsListLoop");
			}
		}
		//public Track SelectedItem
		//{
		//    get
		//    {
		//        Track track = null;
		//        lvPlayList.Dispatcher.Invoke(new Action(delegate { track = lvPlayList.SelectedItem as Track; }));
		//        return track;
		//    }
		//}
		public Track CurrentTrack
		{
			get
			{
				Track track = _playlist.CurrentTrack;//null;
				//Dispatcher.Invoke(new Action(delegate { track = _playlist.History.IsEmpty?null: _playlist[_playlist.History.Last]; }));
				return track;
			}
		}
		public string CurrentFileListPath
		{
			get { return _playlist.Path; }
		}
		public int CurrentTrackId
		{
			get { return _playlist.History.IsEmpty ? -1 : _playlist.History.Last; }
		}

		public Window OwnerWindow { get; set; }

		public PlayList()
		{
			Initialize();
		}

		public PlayList(Window owner)
		{
			OwnerWindow = owner;
			Initialize();
		}

		void Initialize()
		{
			InitializeComponent();
			_playlist.TrackChanged += ChangeTrack;
			_playlist.IsFileLoop = ConfigTools.ConfigFile.IsFileLoop; //Properties.Settings.Default.FileLoop;
			_playlist.IsShuffle = ConfigTools.ConfigFile.IsShuffle; //Properties.Settings.Default.Shuffle;
			_playlist.IsListLoop = ConfigTools.ConfigFile.IsListLoop; //Properties.Settings.Default.ListLoop;
			//lvPlayList.ItemsSource = _playlist;
			tabItem1.DataContext = _playlist;
		}

		void ChangeProperty(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}

		void ChangeTrack(Track track)
		{
			if (TrackChanged != null)
				TrackChanged(track);
		}

		//void ChangeTrack(string newSongUrl)
		//{
		//    if (TrackChanged != null)
		//        TrackChanged(newSongUrl);
		//}

		public void MpActivityChanged(object sender, EventArgs e)
		{
			lvPlayList.Dispatcher.Invoke(new Action(() =>
			                                        	{
			                                        		ReDraw();
			                                        		ScrollToItem(CurrentTrack);
			                                        	}));
		}

		public void Load(string fileName = null)
		{
			if(fileName==null)
			{
				var dialog = new OpenFileDialog {AddExtension = true, Filter = "DACU Playlists|*.dpl"};
				//dialog.DefaultExt = "dpl";
				//dialog.FilterIndex = 0;
				bool? showDialog = dialog.ShowDialog();
				if (showDialog.HasValue && showDialog.Value)
					fileName = dialog.FileName;
			}
			if (String.IsNullOrWhiteSpace(fileName)) return;
			ChangeTrack(null);
			_playlist.Load(fileName);
			if (tabItem1.DataContext == null)
				tabItem1.DataContext = _playlist;
			//if (lvPlayList.ItemsSource == null)
			//    lvPlayList.ItemsSource = _playlist;
		}

		public void Save(string fileName=null)
		{
			if (_playlist.IsEmpty) return;
			if (fileName == null)
			{
				if (!String.IsNullOrWhiteSpace(CurrentFileListPath))
					_playlist.Save();
				else
					return;
			}
			else
				_playlist.Save(fileName);
		}

		private void bLoad_Click(object sender, RoutedEventArgs e)
		{
			/*var dialog = new OpenFileDialog();
			bool? showDialog = dialog.ShowDialog();
			if (showDialog != null && showDialog.Value)
			{
				ChangeTrack("");
				_playlist.Load(dialog.FileName);
				if (lvPlayList.ItemsSource == null)
					lvPlayList.ItemsSource = _playlist;
			}*/
			Load();
		}

		private void bSave_Click(object sender, RoutedEventArgs e)
		{
			var dialog = new SaveFileDialog { AddExtension = true, Filter = "DACU Playlists|*.dpl" };
			//dialog.DefaultExt = "dpl";
			//dialog.FilterIndex = 0;
			bool? showDialog = dialog.ShowDialog();
			if (showDialog.HasValue && showDialog.Value)
				Save(dialog.FileName);
		}

		public Track NextTrack()
		{
			lvPlayList.Dispatcher.Invoke(new Action(
			                             	delegate
			                             		{
			                             			int nextId = _playlist.PlayNext();
													//lvPlayList.SelectedIndex = nextId;
													//ReDraw();
													//ScrollToItem(lvPlayList.SelectedItem);
													//ScrollToItem(_playlist.CurrentTrack);
			                             		}
			                             	));
			return CurrentTrack;
		}

		public Track PrevTrack()
		{
			lvPlayList.Dispatcher.Invoke(new Action(
			                             	delegate
			                             		{
			                             			/*lvPlayList.SelectedIndex =*/ _playlist.PlayPrev();
													//ReDraw();
													//ScrollToItem(_playlist.CurrentTrack);
			                             			//ScrollToItem(lvPlayList.SelectedItem);
			                             		}
			                             	));
			return CurrentTrack;
		}

		public void Clear()
		{
			_playlist.Clear();
		}

		void ReDraw()
		{
			ICollectionView dataView = CollectionViewSource.GetDefaultView(lvPlayList.ItemsSource);
			if (dataView != null)
				dataView.Refresh();
		}

		public void PlayIndex(int? index=null)
		{
			ReDraw();
			if (index.HasValue)
			{
				_playlist.PlayIndex(index.Value);
				//ScrollToItem(_playlist.CurrentTrack);
				//ScrollToItem(lvPlayList.Items.GetItemAt(index.Value));
			}
			else
				ScrollToItem(_playlist.CurrentTrack);
				//_playlist.PlayIndex(lvPlayList.SelectedIndex);
		}

		private void lvPlayList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			//PlayIndex();
		}

		private void bClear_Click(object sender, RoutedEventArgs e)
		{
			MessageBoxResult result = MessageBox.Show(OwnerWindow,
			                                          "Are you sure you want clear playlist?",
			                                          "Playlist clear confirmation",
			                                          MessageBoxButton.YesNo
				);
			if (result == MessageBoxResult.Yes)
				Clear();
		}

		public void ScrollToItem(object item)
		{
			lvPlayList.ScrollIntoView(item);
			//var lvitem = lvPlayList.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem;
			//if(lvitem!=null)
			//    lvitem.Focus();
		}

		private void bDelete_Click(object sender, RoutedEventArgs e)
		{
			var selected = new object[lvPlayList.SelectedItems.Count];
			lvPlayList.SelectedItems.CopyTo(selected,0);
			/*for (int i = 0; i < lvPlayList.SelectedItems.Count; i++)
				selected[i] = _playlist.IndexOf(lvPlayList.SelectedItems[i] as Track);*/
			for (int i = 0; i < selected.Length; i++)
				_playlist.RemoveAt(_playlist.IndexOf(selected[i] as Track));
			//_playlist.Remove(lvPlayList.SelectedItem as Track);
			ReDraw();
		}

		private void bAdd_Click(object sender, RoutedEventArgs e)
		{
			AddMenu.PlacementTarget = bAdd;
			AddMenu.Placement = PlacementMode.Bottom;
			AddMenu.IsOpen = true;
		}

		private void VKMenuItemClick(object sender, RoutedEventArgs e)
		{
			var addTrackWindow = new AddTrackWindow(OwnerWindow);
			if (addTrackWindow.ShowDialog(TrackType.VKontakte) ?? false)
				if (addTrackWindow.Playlist != null && !addTrackWindow.Playlist.IsEmpty)
					_playlist.AddRange(addTrackWindow.Playlist);
		}

		private void FileMenuItemClick(object sender, RoutedEventArgs e)
		{
			var addTrackWindow = new AddTrackWindow(OwnerWindow);
			if (addTrackWindow.ShowDialog(TrackType.File) ?? false)
				if (addTrackWindow.Playlist != null && !addTrackWindow.Playlist.IsEmpty)
					_playlist.AddRange(addTrackWindow.Playlist);
		}

		private void UrlMenuItemClick(object sender, RoutedEventArgs e)
		{
			var addTrackWindow = new AddTrackWindow(OwnerWindow);
			if (addTrackWindow.ShowDialog(TrackType.Url) ?? false)
				if (addTrackWindow.Track != null)
					_playlist.Add(addTrackWindow.Track);
		}

		private void bAdd_ContextMenuOpening(object sender, ContextMenuEventArgs e)
		{
			e.Handled = true;
		}

		private void UserControl_Loaded(object sender, RoutedEventArgs e)
		{
			OwnerWindow = Window.GetWindow(this);
		}

		private void HandleDoubleClick(object sender, MouseButtonEventArgs e)
		{
			var track = ((ListViewItem)sender).Content as Track;
			PlayIndex(_playlist.IndexOf(track));
		}

		private void lvPlayList_Drop(object sender, DragEventArgs e)
		{
			if (!e.Data.GetDataPresent(DataFormats.FileDrop, true)) return;
			var fileNames = e.Data.GetData(DataFormats.FileDrop, true);
			if (fileNames != null && (fileNames is string[] && (fileNames as string[]).Length == 1))
			{
				string ext = Path.GetExtension((fileNames as string[])[0]);
				if (ext != null)
				{
					ext = ext.ToLower();
					ext = ext.Trim(new[] {'.'});
					if (ext == "dpl")
					{
						_playlist.Load((fileNames as string[])[0]);
						return;
					}
				}
			}
			if (fileNames != null && (fileNames is string[] && (fileNames as string[]).Length > 0))
			{
				foreach (string filename in (fileNames as string[]))
				{
					if (Utils.IsKnownFormat(Path.GetExtension(filename)))
					{
						var track = new Track(filename, TrackType.File);
						track.GetInfoFromFile();
						_playlist.Add(track);
					}
				}
			}
		}
	}
}
